<?php
namespace app\service;

use think\facade\Config;
use think\facade\Log;

class NanobananaApiService
{
    private $apiUrl;
    private $apiToken;

    private $defaultConfig;

    public function __construct()
    {
        $config = Config::get('nanobanana');
        $this->apiUrl = $config['api_url'] ?? 'https://api.nanobananaapi.ai/api/v1';
        $this->apiToken = $config['api_token'] ?? '';
        $this->defaultConfig = $config['default'] ?? [];
    }

    /**
     * 生成图片（使用 generate-pro 接口）
     * 
     * @param string $prompt 文本提示
     * @param array $options 可选参数
     *   - imageUrls: 图片URL数组（可选，用于图片编辑模式）
     *   - resolution: 分辨率，默认"2K"
     *   - aspectRatio: 宽高比，默认"16:9"
     *   - callBackUrl: 回调URL
     * @return array API响应结果
     * @throws \Exception
     */
    public function generatePro($prompt, $options = [])
    {
        $url = $this->apiUrl . '/nanobanana/generate-pro';
        
        // 构建请求数据
        $data = [
            'prompt' => $prompt,
            'resolution' => $options['resolution'] ?? $this->defaultConfig['resolution'] ?? '2K',
            'aspectRatio' => $options['aspectRatio'] ?? $this->defaultConfig['aspectRatio'] ?? '16:9',
        ];
        
        // 处理 imageUrls：如果提供了图片URL数组，使用它；否则使用空字符串数组（文生图模式）
        if (!empty($options['imageUrls']) && is_array($options['imageUrls'])) {
            // 过滤掉空字符串，如果过滤后还有值，使用过滤后的数组
            $filteredUrls = array_filter($options['imageUrls'], function($url) {
                return !empty(trim($url));
            });
            $data['imageUrls'] = !empty($filteredUrls) ? array_values($filteredUrls) : [''];
        } else {
            // 文生图模式，使用空字符串数组
            $data['imageUrls'] = [''];
        }
        
        // 如果提供了回调URL，添加到请求中
        if (!empty($options['callBackUrl'])) {
            $data['callBackUrl'] = $options['callBackUrl'];
        }
        Log::info('Nanobanana API调用'.var_export($data, true));
        try {
            $response = $this->httpPost($url, json_encode($data));
            $result = json_decode($response, true);
            
            // 记录请求日志
            Log::info('Nanobanana API调用', [
                'url' => $url,
                'prompt' => $prompt,
                'request_data' => $data,
                'response' => $result
            ]);
            
            return $result;
        } catch (\Exception $e) {
            Log::error('Nanobanana API调用失败', [
                'url' => $url,
                'prompt' => $prompt,
                'request_data' => $data,
                'error' => $e->getMessage()
            ]);
            throw $e;
        }
    }

    /**
     * 生成图片（使用 generate 标准接口）
     * 
     * @param string $prompt 文本提示
     * @param string $type 生成类型：TEXTTOIAMGE（文本生成图片）或 IMAGETOIAMGE（图片编辑）
     * @param array $options 可选参数
     *   - numImages: 图片数量，默认1
     *   - image_size: 图片尺寸，默认16:9
     *   - callBackUrl: 回调URL
     *   - imageUrls: 图片URL数组（用于图片编辑模式）
     * @return array API响应结果
     * @throws \Exception
     */
    public function generateStandard($prompt, $type = 'TEXTTOIAMGE', $options = [])
    {
        $url = $this->apiUrl . '/nanobanana/generate';
        
        // 构建请求数据
        $data = [
            'prompt' => $prompt,
            'numImages' => $options['numImages'] ?? $this->defaultConfig['numImages'] ?? 1,
            'type' => $type,
            'image_size' => $options['image_size'] ?? $this->defaultConfig['image_size'] ?? '16:9',
        ];
        
        // 如果提供了回调URL，添加到请求中
        if (!empty($options['callBackUrl'])) {
            $data['callBackUrl'] = $options['callBackUrl'];
        }
        
        // 如果提供了图片URL数组，添加到请求中
        if (!empty($options['imageUrls']) && is_array($options['imageUrls'])) {
            $data['imageUrls'] = $options['imageUrls'];
        }
        
        try {
            $response = $this->httpPost($url, json_encode($data));
            $result = json_decode($response, true);
            
            // 记录请求日志
            Log::info('Nanobanana API调用（generate标准接口） - URL: ' . $url . ' | Type: ' . $type . ' | Prompt: ' . $prompt . ' | Request: ' . json_encode($data, JSON_UNESCAPED_UNICODE) . ' | Response: ' . json_encode($result, JSON_UNESCAPED_UNICODE));
            
            return $result;
        } catch (\Exception $e) {
            Log::error('Nanobanana API调用失败（generate标准接口） - URL: ' . $url . ' | Type: ' . $type . ' | Prompt: ' . $prompt . ' | Request: ' . json_encode($data, JSON_UNESCAPED_UNICODE) . ' | Error: ' . $e->getMessage());
            throw $e;
        }
    }

    /**
     * 生成图片（文本生成图片或图片编辑）- 调用标准接口
     * 
     * @param string $prompt 文本提示
     * @param string $type 生成类型：TEXTTOIAMGE（文本生成图片）或 IMAGETOIAMGE（图片编辑）
     * @param array $options 可选参数
     *   - numImages: 图片数量，默认1
     *   - image_size: 图片尺寸，默认16:9
     *   - callBackUrl: 回调URL
     *   - imageUrls: 图片URL数组（用于图片编辑模式）
     * @return array API响应结果
     * @throws \Exception
     */
    public function generate($prompt, $type = 'TEXTTOIAMGE', $options = [])
    {
        return $this->generateStandard($prompt, $type, $options);
    }

    /**
     * 文本生成图片
     * 
     * @param string $prompt 文本提示
     * @param array $options 可选参数
     *   - aspectRatio: 宽高比，默认16:9
     *   - resolution: 分辨率，默认2K
     *   - callBackUrl: 回调URL
     * @return array API响应结果
     * @throws \Exception
     */
    public function textToImage($prompt, $options = [])
    {
        // 兼容旧参数名
        if (isset($options['image_size']) && !isset($options['aspectRatio'])) {
            $options['aspectRatio'] = $options['image_size'];
        }
        return $this->generatePro($prompt, $options);
    }

    /**
     * 图片编辑
     * 
     * @param string $prompt 文本提示
     * @param array $imageUrls 输入图片URL数组
     * @param array $options 可选参数
     *   - aspectRatio: 宽高比，默认16:9
     *   - resolution: 分辨率，默认2K
     *   - callBackUrl: 回调URL
     * @return array API响应结果
     * @throws \Exception
     */
    public function imageToImage($prompt, $imageUrls, $options = [])
    {
        $options['imageUrls'] = $imageUrls;
        // 兼容旧参数名
        if (isset($options['image_size']) && !isset($options['aspectRatio'])) {
            $options['aspectRatio'] = $options['image_size'];
        }
        return $this->generatePro($prompt, $options);
    }

    /**
     * 发送HTTP POST请求
     * 
     * @param string $url 请求URL
     * @param string $data JSON格式的请求数据
     * @return string 响应内容
     * @throws \Exception
     */
    private function httpPost($url, $data)
    {
        $headers = [
            'Authorization: Bearer ' . $this->apiToken,
            'Content-Type: application/json',
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 60秒超时
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); // 30秒连接超时
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            Log::error('Nanobanana API CURL错误', [
                'url' => $url,
                'error' => $error
            ]);
            throw new \Exception('CURL错误：' . $error);
        }
        
        if ($httpCode >= 400) {
            Log::error('Nanobanana API HTTP错误', [
                'url' => $url,
                'http_code' => $httpCode,
                'response' => $response
            ]);
            throw new \Exception('HTTP错误：' . $httpCode . '，响应：' . $response);
        }
        
        return $response;
    }
}

